package zap

import (
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/buffer"
	"go.uber.org/zap/zapcore"
	"os"
	"regexp"
	"time"
)

// logEncoder 时间分片和level分片同时做
type logEncoder struct {
	zapcore.Encoder
	errFile     *os.File
	file        *os.File
	currentDate string
}

const (
	BuleColor   = "\033[34m"
	YellowColor = "\033[33m"
	RedColor    = "\033[31m"
	ResetColor  = "\033[0m"
)

func myEncodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
	switch level {
	case zapcore.InfoLevel:
		enc.AppendString(BuleColor + "INFO" + ResetColor)
	case zapcore.WarnLevel:
		enc.AppendString(YellowColor + "WARN" + ResetColor)
	case zapcore.ErrorLevel, zapcore.DPanicLevel, zapcore.PanicLevel, zapcore.FatalLevel:
		enc.AppendString(RedColor + "ERROR" + ResetColor)
	default:
		enc.AppendString(level.String())
	}
}

// 去除 ANSI 颜色代码
func stripAnsi(str string) string {
	ansiRegex := regexp.MustCompile("\033\\[[0-9;]*m")
	return ansiRegex.ReplaceAllString(str, "")
}
func (e *logEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
	// 先调用原始的 EncodeEntry 方法生成日志行
	buff, err := e.Encoder.EncodeEntry(entry, fields)
	if err != nil {
		return nil, err
	}
	data := buff.String()
	buff.Reset()
	buff.AppendString("[5title_gin] " + data)
	// 去掉 ANSI 颜色代码
	cleanData := stripAnsi(buff.String())
	// 时间分片
	now := time.Now().Format("2006-01-02")
	if e.currentDate != now {
		os.MkdirAll(fmt.Sprintf("logs/%s", now), 0755)
		// 时间不同，先创建目录
		name := fmt.Sprintf("logs/%s/out.log", now)
		file, err := os.OpenFile(name, os.O_CREATE|os.O_APPEND|os.O_WRONLY|os.O_SYNC, 0666)
		if err != nil {
			fmt.Println("创建文件失败", err)
		}
		e.file = file
		e.currentDate = now
	}

	// 如果是错误日志，处理 err.log
	if entry.Level >= zapcore.ErrorLevel {
		if e.errFile == nil {
			name := fmt.Sprintf("logs/%s/err.log", now)
			file, err := os.OpenFile(name, os.O_CREATE|os.O_APPEND|os.O_WRONLY|os.O_SYNC, 0644)
			if err != nil {
				fmt.Println("创建文件失败", err)
				return nil, err
			}
			e.errFile = file
		}
		e.errFile.WriteString(cleanData)
	}

	if e.currentDate == now && e.file != nil {
		e.file.WriteString(cleanData)
	}

	return buff, nil
}

func InitLog() *zap.Logger {
	// 配置 zap
	cfg := zap.NewDevelopmentConfig()
	cfg.EncoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
	cfg.EncoderConfig.EncodeLevel = myEncodeLevel

	// 创建自定义 Encoder
	encoder := &logEncoder{
		Encoder: zapcore.NewConsoleEncoder(cfg.EncoderConfig),
	}

	// 创建 Core
	core := zapcore.NewCore(
		encoder,
		zapcore.AddSync(os.Stdout), // 确保日志立即写入
		zapcore.DebugLevel,         // 允许所有级别的日志
	)

	// 创建 Logger
	logger := zap.New(core, zap.AddCaller())

	// 替换全局日志
	zap.ReplaceGlobals(logger)
	zap.S().Info("🌟日志初始化成功!")
	return logger
}
